#ifndef APP_APPLICATION_h_H_H_
#define APP_APPLICATION_h_H_H_


#include <boost/signal.hpp>
#include "Parameter.h"
#include "Observer.h"


namespace App
{
   class Document;
   class DocumentObject;
   class Property;
}


class ParameterManager;
class App_Application
{
public:
	App_Application(ParameterManager *pcSysParamMngr, ParameterManager *pcUserParamMngr,std::map<std::string,std::string> &mConfig);
	~App_Application(void);

public:
	static void init();

	static void initTypes();
	static void initConfig(); 
    static void destruct(void);
    static void destructObserver(void);

	static void ExtractUserPath();
	static void LoadParameters(void);
    static std::map<std::string,std::string> &Config(void){return mConfig;}
    ParameterManager& GetSystemParameter(void) ;
    ParameterManager& GetUserParameter(void) ;
              
	static void initApplication(void);
	friend App_Application &GetApp_Application(void);


	// const char* getExecutableName(void) const;

   
	 static void logStatus(void);
	 static void SaveEnv(const char *);


	static App_Application* _pcSingleton;

	 std::map<std::string,ParameterManager *> mpcPramManager;

	 static std::map<std::string,std::string> mConfig;

	 std::map<std::string,std::string> &_mConfig;
   
	 void addImportType(const char* Type, const char* ModuleName);

	 struct FileTypeItem {
		 std::string filter;
		 std::string module;
		 std::vector<std::string> types;
	 };

	 std::vector<FileTypeItem> _mImportTypes;
	 std::vector<FileTypeItem> _mExportTypes;

    Base::Reference<ParameterGrp>                 GetParameterGroupByPath(const char* sName);
	ParameterManager *                                GetParameterSet(const char* sName) const;
	const std::map<std::string,ParameterManager *> &  GetParameterSetList(void) const;
	void AddParameterSet(const char* sName);
	void RemoveParameterSet(const char* sName);

	App::Document* openDocument(const char * FileName);
	static void openDocument_s(const char * FileName);
	static void addObject(const char * objectName);
	void closeAllDocuments();

	void slotNewObject(const App::DocumentObject&);
	void slotDeletedObject(const App::DocumentObject&);
	void slotChangedObject(const App::DocumentObject&, const App::Property& Prop);
	void slotRenamedObject(const App::DocumentObject&);
	void slotActivatedObject(const App::DocumentObject&);


	std::vector<std::string> getImportTypes(const char* Module) const;
	/// Return a list of all filetypes.
	std::vector<std::string> getImportTypes(void) const;

	std::map<std::string, std::string> getImportFilters(const char* Type) const;
	/// Return a list of all import filters.
	std::map<std::string, std::string> getImportFilters(void) const;

	std::vector<std::string> getExportTypes(const char* Module) const;
	/// Return a list of all filetypes.
	std::vector<std::string> getExportTypes(void) const;

	std::map<std::string, std::string> getExportFilters(const char* Type) const;
	/// Return a list of all export filters.
	std::map<std::string, std::string> getExportFilters(void) const;

	 static std::string FindHomePath();

	/// signal on new Object
	boost::signal<void (const App::DocumentObject&)> signalNewObject;
	//boost::signal<void (const App::DocumentObject&)>     m_sig;
	/// signal on deleted Object
	boost::signal<void (const App::DocumentObject&)> signalDeletedObject;
	/// signal on changed Object
	boost::signal<void (const App::DocumentObject&, const App::Property&)> signalChangedObject;
	/// signal on renamed Object
	boost::signal<void (const App::DocumentObject&)> signalRenamedObject;
	/// signal on activated Object
	boost::signal<void (const App::DocumentObject&)> signalActivatedObject;


	const char* GetHomePath(void) const;
	const char* getExecutableName(void) const;
	static std::string getUserAppDataDir();
	static std::string getResourceDir();
	static std::string getHelpDir();




     static void importObject(const char * Name=0l, const char * UserName=0l);
	 App::Document* newDocument(const char * Name=0l, const char * UserName=0l);
	 static void  newDocument_S(const char * Name, const char * UserName);
	 std::map<std::string,App::Document*> DocMap;
     App::Document* _pActiveDoc;
     friend class App::Document;

     void setActiveDocument(App::Document* pDoc);
     void setActiveDocument(const char *Name);

	 std::string getUniqueDocumentName(const char *Name) const;
	 App::Document* getActiveDocument(void) const;

	 bool closeDocument(const char* name);

	 std::vector<App::Document*> getDocuments() const;
	 App::Document* getDocument(const char *Name) const;
	 /// gets the (internal) name of the document
	 const char * getDocumentName(const App::Document* ) const;

	 boost::signal<void (const App::Document&)> signalNewDocument;
	 /// signal on deleted Document
	 boost::signal<void (const App::Document&)> signalDeleteDocument;
	 /// signal on relabeling Document (user name)
	 boost::signal<void (const App::Document&)> signalRelabelDocument;
	 /// signal on renaming Document (internal name)
	 boost::signal<void (const App::Document&)> signalRenameDocument;
	 /// signal on activating Document
	 boost::signal<void (const App::Document&)> signalActiveDocument;
	 /// signal on saving Document
	 boost::signal<void (const App::Document&)> signalSaveDocument;
	 /// signal on restoring Document
	 boost::signal<void (const App::Document&)> signalRestoreDocument;

	  boost::signal<void (const App::Document&)> signalResetDocument;

     boost::signal<void ()> signalDeletedDocument;
	  boost::signal<void (const App::Document&)> signalNewScene;

	  //////////////////////////////////////////////////////////////////////////




private:

 	static ParameterManager *_pcSysParamMngr;
 	static ParameterManager *_pcUserParamMngr;

	 //App::Document* _pActiveDoc;

};

inline App_Application&GetApp_Application(void){
	return *App_Application::_pcSingleton;
}
#endif